package com.fingersoft.feature.filemanager

import android.content.Context
import android.net.Uri
import android.util.Log
import cn.fingersoft.feature.filemanager.FileManagerContextBase
import cn.fingersoft.io.rong.imkit.utils.MyFileTypeUtils
import com.fingersoft.business.BusinessContext
import com.fingersoft.common.ICallback
import com.fingersoft.feature.filemanager.dao.FileDaoUtils
import com.fingersoft.feature.filemanager.dao.bean.FileBean
import com.fingersoft.feature.filemanager.dao.bean.FoldersBean
import com.fingersoft.feature.filemanager.dao.bean.YunpanFilesBean
import com.fingersoft.im.api.UserAgent
import com.fingersoft.im.api.base.BaseModelCallback2
import com.fingersoft.im.api.base.BaseResponse2
import com.fingersoft.im.utils.AppConfigUtils
import com.fingersoft.im.utils.AppUtils
import com.fingersoft.im.utils.JSONUtils
import com.fingersoft.im.utils.YunpanFileParam
import com.fingersoft.plugins.PluginsContext
import com.google.gson.Gson
import com.lzy.okgo.OkGo
import com.lzy.okgo.request.BaseRequest
import com.shougang.call.util.PinyinUtils
import okhttp3.Call
import okhttp3.Response
import org.json.JSONArray
import org.json.JSONObject
import java.io.File
import java.net.URLEncoder
import java.util.*

/**
 * Created by liubinbin on 2017/9/9.
 */
class SealFileManagerContext : FileManagerContextBase() {

    override fun getPreviewurl(context: Context?, path: String?, params: String?, callback: ICallback<Any>?) {
        OkGo.post(AppUtils.getApiUrl(path, AppUtils.J_ECODE))
            .headers("Emp-Info", JSONUtils.toJsonString(UserAgent(context, AppUtils.getTokenInfo().userToken, AppUtils.getTokenInfo().did)))
            .upJson(params)
            .execute(object : BaseModelCallback2<BaseResponse2<*>>(BaseResponse2::class.java) {
                override fun onSuccess(getYunPanResponse: BaseResponse2<*>?, call: Call, response: Response) {
                    if (getYunPanResponse == null) {
                        return
                    }
                    super.onSuccess(getYunPanResponse, call, response)
                    if (AppUtils.showApiSucceedErrorToast(getYunPanResponse)) {
                        callback!!.onError()
                        return
                    }
                    callback!!.onSuccess(getYunPanResponse.data)
                }

                override fun onError(call: Call?, response: Response?, e: Exception?) {
                    super.onError(call, response, e)
                    callback!!.onError()
                }

                    override fun onBefore(request: BaseRequest<*>?) {
                        super.onBefore(request)
                    }

                    override fun onAfter(getYunPanResponse: BaseResponse2<*>, e: Exception?) {
                        super.onAfter(getYunPanResponse, e)
                    }
            })
    }

    override fun isYunPan(context: Context?): Boolean {
        return AppConfigUtils.getAppConfigInfo(context!!).isYunpan
    }

    override fun isMy_file(context: Context?): Boolean {
        return AppConfigUtils.getAppConfigInfo(context!!).isMy_file
    }

    override fun isApp_file_local_storage(context: Context?): Boolean {
        return AppConfigUtils.getAppConfigInfo(context!!).isApp_file_local_storage
    }

    override fun getShare_module(context: Context?): String {
        val context = context!!
        return if (AppConfigUtils.getAppConfigInfo(context).share_module == null) "" else AppConfigUtils.getAppConfigInfo(context).share_module;
    }

    override fun sendYunFile(context: Context, file: File, yunpanFilesBean: YunpanFilesBean) {
        val uri = Uri.parse("file://" + file.path)
        val name = yunpanFilesBean.name
        val size = yunpanFilesBean.bytes
        val localPath = Uri.parse(yunpanFilesBean.fileUrl)
        BusinessContext.im?.sendFileMessage(context, localPath, name, size, uri)
    }


    override fun sendMyFile(context: Context, file: File, yunpanFilesBean: FileBean) {
        val uri = Uri.parse("file://" + file.getPath())
        val name = yunpanFilesBean.name
        val size = yunpanFilesBean.size as Long
        val localPath = Uri.parse(yunpanFilesBean.localPath)
        BusinessContext.im?.sendFileMessage(context, localPath, name, size, uri)
    }

    override fun openYunPanFile(context: Context?, path: String?, name: String?, id: String?) {
        PluginsContext.instance.startYunFile(context, path, name, id)
    }

    override fun openMyFile(context: Context?, path: String?, name: String?, id: String?) {
        PluginsContext.instance.startMyFile(context, path, name, id)
    }

    override fun DeleteFolder(context: Context?, path: String?, params: String?, callback: ICallback<*>?) {
        OkGo.post(AppUtils.getApiUrl(path, AppUtils.J_ECODE))
            .headers("Emp-Info", JSONUtils.toJsonString(UserAgent(context, AppUtils.getTokenInfo().userToken, AppUtils.getTokenInfo().did)))
            .upJson(params)
            .execute(object : BaseModelCallback2<BaseResponse2<*>>(BaseResponse2::class.java) {
                override fun onSuccess(getYunPanResponse: BaseResponse2<*>, call: Call, response: Response) {
                    super.onSuccess(getYunPanResponse, call, response)
                    if (AppUtils.showApiSucceedErrorToast(getYunPanResponse)) {
                        callback!!.onError()
                        return
                    }

                    callback!!.onSuccess()
                }

                override fun onError(call: Call?, response: Response?, e: Exception?) {
                    super.onError(call, response, e)
                    callback!!.onError()
                }

                    override fun onBefore(request: BaseRequest<*>?) {
                        super.onBefore(request)
                    }

                    override fun onAfter(getYunPanResponse: BaseResponse2<*>, e: Exception?) {
                        super.onAfter(getYunPanResponse, e)
                    }
            })
    }

    override fun UplodeFile(context: Context?, path: String?, params: YunpanFileParam?, callback: ICallback<*>?) {
        val request = OkGo.post(AppUtils.getApiUrl(path, AppUtils.J_ECODE))
            .headers("Emp-Info", JSONUtils.toJsonString(UserAgent(context, AppUtils.getTokenInfo().userToken, AppUtils.getTokenInfo().did)))
            //.upJson(params)
            .params("name", params!!.name)
            .params("md5", params.md5)
            .params("folderId", params.folderId)
        val fileName = params.file.name
        request.params("file", params.file, if (needEncode(fileName)) URLEncoder.encode(fileName, "UTF-8") else fileName)

        request.execute(object : BaseModelCallback2<BaseResponse2<*>>(BaseResponse2::class.java) {
            override fun onSuccess(getYunPanResponse: BaseResponse2<*>?, call: Call, response: Response) {
                super.onSuccess(getYunPanResponse, call, response)
                if (AppUtils.showApiSucceedErrorToast(getYunPanResponse)) {
                    callback?.onError()
                    return
                }

                if (getYunPanResponse?.data != null) {
                    val gson = Gson()
                    val jsonStr = gson.toJson(getYunPanResponse.data)
                    val result = JSONObject(jsonStr)

                    val filesList = ArrayList<YunpanFilesBean>()
                    val application = Gson().fromJson(jsonStr, YunpanFilesBean::class.java)
                    filesList.add(application)
                    FileDaoUtils.instance.saveYunPanFiles(filesList)
                    callback?.onSuccess()
                } else {
                    Log.e("FileManager", "Unknown Error: upload file error")
                    callback?.onError()
                }
            }

            override fun onError(call: Call?, response: Response?, e: Exception?) {
                super.onError(call, response, e)
                callback?.onError()
            }
        })
    }

    private fun needEncode(str: String): Boolean {
        for (c: Char in str) {
            if (c <= '\u001f' || c >= '\u007f') {
                var file = File(str)
                return true
            }
        }
        return false
    }

    private fun encodeString(str: String): String {
        var fName = File(str).name
        for (c: Char in str) {
            if (c <= '\u001f' || c >= '\u007f') {
                var file = File(str)
                fName = PinyinUtils.getPinYin(file.name).replace(" ", "")
                break
            }
        }
        if (needEncode(fName)) {
            fName = "rongFile_" + System.currentTimeMillis() + str.substring(str.lastIndexOf("."))
        }
        return fName
    }

    override fun saveIMFile(context: Context?, path: String?, params: YunpanFileParam?, callback: ICallback<*>?) {
        val params = params!!
        OkGo.post(AppUtils.getApiUrl(path, AppUtils.J_ECODE))
            .headers("Emp-Info", JSONUtils.toJsonString(UserAgent(context, AppUtils.getTokenInfo().userToken, AppUtils.getTokenInfo().did)))
            //.upJson(params)
            .params("name", params.name)
            .params("md5", params.md5)
            .params("file", params.file)
            .params("folderId", params.folderId)
            .params("url", params.url)
            .execute(object : BaseModelCallback2<BaseResponse2<*>>(BaseResponse2::class.java) {
                override fun onSuccess(getYunPanResponse: BaseResponse2<*>, call: Call, response: Response) {
                    super.onSuccess(getYunPanResponse, call, response)
                    if (AppUtils.showApiSucceedErrorToast(getYunPanResponse)) {
                        callback!!.onError()
                        return
                    }

                    if (getYunPanResponse.data != null) {
                        val gson = Gson()
                        val jsonStr = gson.toJson(getYunPanResponse.data)
                        val result = JSONObject(jsonStr)

                        val filesList = ArrayList<YunpanFilesBean>()
                        val application = Gson().fromJson(jsonStr, YunpanFilesBean::class.java)
                        filesList.add(application)
                        FileDaoUtils.instance.saveYunPanFiles(filesList)

                    }
                    callback!!.onSuccess()
                }

                override fun onError(call: Call?, response: Response?, e: Exception?) {
                    super.onError(call, response, e)
                    callback!!.onError()
                }

                override fun onBefore(request: BaseRequest<*>?) {
                    super.onBefore(request)
                }

                override fun onAfter(getYunPanResponse: BaseResponse2<*>, e: Exception?) {
                    super.onAfter(getYunPanResponse, e)
                }
            })
    }

    override fun CreateFolder(context: Context?, path: String?, params: String?, callback: ICallback<*>?) {
        OkGo.post(AppUtils.getApiUrl(path, AppUtils.J_ECODE))
            .headers("Emp-Info", JSONUtils.toJsonString(UserAgent(context, AppUtils.getTokenInfo().userToken, AppUtils.getTokenInfo().did)))
            .upJson(params)
            .execute(object : BaseModelCallback2<BaseResponse2<*>>(BaseResponse2::class.java) {
                override fun onSuccess(getYunPanResponse: BaseResponse2<*>, call: Call, response: Response) {
                    super.onSuccess(getYunPanResponse, call, response)
                    if (AppUtils.showApiSucceedErrorToast(getYunPanResponse)) {
                        callback!!.onError()
                        return
                    }

                    if (getYunPanResponse.data != null) {
                        val gson = Gson()
                        val jsonStr = gson.toJson(getYunPanResponse.data)
                        val result = JSONObject(jsonStr)
                        val foldersList = ArrayList<FoldersBean>()
                        val application = Gson().fromJson(jsonStr, FoldersBean::class.java)
                        foldersList.add(application)
                        FileDaoUtils.instance.saveFolders(foldersList)


                    }
                    callback!!.onSuccess()
                }

                override fun onError(call: Call?, response: Response?, e: Exception?) {
                    super.onError(call, response, e)
                    callback!!.onError()
                }

                override fun onBefore(request: BaseRequest<*>?) {
                    super.onBefore(request)
                }

                override fun onAfter(getYunPanResponse: BaseResponse2<*>, e: Exception?) {
                    super.onAfter(getYunPanResponse, e)
                }
            })
    }

    override fun ChangeFile(context: Context?, path: String?, params: String?, callback: ICallback<*>?) {
        OkGo.post(AppUtils.getApiUrl(path, AppUtils.J_ECODE))
            .headers("Emp-Info", JSONUtils.toJsonString(UserAgent(context, AppUtils.getTokenInfo().userToken, AppUtils.getTokenInfo().did)))
            .upJson(params)
            .execute(object : BaseModelCallback2<BaseResponse2<*>>(BaseResponse2::class.java) {
                override fun onSuccess(getYunPanResponse: BaseResponse2<*>, call: Call, response: Response) {
                    super.onSuccess(getYunPanResponse, call, response)
                    if (AppUtils.showApiSucceedErrorToast(getYunPanResponse)) {
                        callback!!.onError()
                        return
                    }

                    if (getYunPanResponse.data != null) {
                        val gson = Gson()
                        val jsonStr = gson.toJson(getYunPanResponse.data)
                        val result = JSONObject(jsonStr)
                        val foldersList = ArrayList<YunpanFilesBean>()
                        val application = Gson().fromJson(jsonStr, YunpanFilesBean::class.java)
                        foldersList.add(application)
                        FileDaoUtils.instance.saveYunPanFiles(foldersList)
                    }
                    callback!!.onSuccess()
                }

                override fun onError(call: Call?, response: Response?, e: Exception?) {
                    super.onError(call, response, e)
                    callback!!.onError()
                }

                override fun onBefore(request: BaseRequest<*>?) {
                    super.onBefore(request)
                }

                override fun onAfter(getYunPanResponse: BaseResponse2<*>, e: Exception?) {
                    super.onAfter(getYunPanResponse, e)
                }
            })
    }

    override fun getAllYunPan(context: Context?, path: String?, params: String, callback: ICallback<*>?) {
        OkGo.post(AppUtils.getApiUrl(path, AppUtils.J_ECODE))
            .headers("Emp-Info", JSONUtils.toJsonString(UserAgent(context, AppUtils.getTokenInfo().userToken, AppUtils.getTokenInfo().did)))
            .upJson(params)
            .execute(object : BaseModelCallback2<GetYunPanResponse>(GetYunPanResponse::class.java) {
                override fun onSuccess(getYunPanResponse: GetYunPanResponse, call: Call, response: Response) {
                    super.onSuccess(getYunPanResponse, call, response)
                    if (AppUtils.showApiSucceedErrorToast(getYunPanResponse)) {
                        callback!!.onError()
                        return
                    }
                    val userStorage = com.fingersoft.feature.filemanager.dao.AppUtils.getUserStorage()
                    if (getYunPanResponse.data != null) {
                        val gson = Gson()
                        val jsonStr = gson.toJson(getYunPanResponse.data)
                        val result = JSONObject(jsonStr)
                        var data_folders: JSONArray? = null
                        var data_files: JSONArray? = null
                        var data_storage: JSONObject? = null
                        try {
                            data_folders = result.getJSONArray("folders")
                            data_files = result.getJSONArray("files")
                            data_storage = result.getJSONObject("userStorage")
                        } catch (e: Exception) {

                        }
                        if (data_folders != null && data_folders.length() != 0) {
                            val foldersList = ArrayList<FoldersBean>()
                            for (i in 0 until data_folders.length()) {
                                val application = Gson().fromJson(data_folders.get(i).toString(), FoldersBean::class.java)
                                foldersList.add(application)
                            }
                            FileDaoUtils.instance.saveFolders(foldersList)
                        }
                        if (data_files != null && data_files.length() != 0) {
                            val filesList = ArrayList<YunpanFilesBean>()
                            for (i in 0 until data_files.length()) {
                                val application = Gson().fromJson(data_files.get(i).toString(), YunpanFilesBean::class.java)
                                filesList.add(application)
                            }
                            FileDaoUtils.instance.saveYunPanFiles(filesList)
                        }
                        if (data_storage != null) {
                            // ":{"total":"2GB","used":"254B"}
                            userStorage.used = data_storage.getString("used")
                            userStorage.total = data_storage.getString("total")
                        }
                    }
                    userStorage.timestamp = getYunPanResponse.timestamp;
                    com.fingersoft.feature.filemanager.dao.AppUtils.saveUserStorage(userStorage);
                    callback!!.onSuccess()
                }

                override fun onError(call: Call?, response: Response?, e: Exception?) {
                    super.onError(call, response, e)
                    callback!!.onError()
                }
            })

    }


    companion object {
        var instance = FileManagerContext()

        fun saveDownLoadFileInfo(path: String?, name: String?, size: Long?, type: String?, time: Long) {
            val bean = FileBean()
            bean.id = time.toString()
            bean.localPath = path
            bean.name = name
            bean.size = size
            bean.type = type
            bean.time = time
            instance.saveDownLoadFile(bean)
        }

        fun savePreviewFileInfo(uid: String, path: String, name: String?, size: Long?, type: String?) {
            val bean = FileBean()
            bean.id = uid
            bean.localPath = path
            bean.name = name
            bean.size = size
            bean.type = type
            bean.time = System.currentTimeMillis()
            instance.saveDownLoadFile(bean)
        }

        fun deleteMyFile(path: String?) {

            instance.deleteMyFileByPath(path)
        }
    }

    override fun getIsLogin(): Boolean {
        return AppUtils.isLogged()
    }

    override fun getUid(): String? {
        return AppUtils.getUser().userId
    }

    override fun getFileTypeImgId(fileName: String?): Int {
        return MyFileTypeUtils.getInstance().fileTypeImageId(fileName)
    }
}
